package com.zzzzzz.account.dao;

import java.util.List;

import org.bson.types.ObjectId;
import org.springframework.stereotype.Repository;

import com.google.code.morphia.query.Query;
import com.google.code.morphia.query.UpdateOperations;
import com.zzzzzz.account.model.User;
import com.zzzzzz.common.util.StringPool;
import com.zzzzzz.common.util.Validator;
import com.zzzzzz.core.dao.morphia.BaseDao;
import com.zzzzzz.core.exception.NoSuchUserException;

@Repository
public class UserDao extends BaseDao {

	private static final String _NO_SUCH_ENTITY_WITH_KEY = "No User exists with the key {";
	private static final String _NO_SUCH_ENTITY_WITH_PRIMARY_KEY = "No User exists with the primary key ";
	
	public User findByEmail(String email) throws NoSuchUserException {
		User user = datastore.find(User.class, "email", email).get();
		if(user == null) {
			throw new NoSuchUserException(_NO_SUCH_ENTITY_WITH_KEY + "email=" + email + StringPool.CLOSE_CURLY_BRACE);
		}
		return user;
	}

	public void editStatus(String userId, Integer status) {
		Query<User> query = datastore.createQuery(User.class);
		query.filter("_id", ObjectId.massageToObjectId(userId));
		datastore.update(query, datastore.createUpdateOperations(User.class).set("status", status));
	}

	public User findById(String userId) throws NoSuchUserException {
		User user = datastore.find(User.class, "_id", ObjectId.massageToObjectId(userId)).get();
		if(user == null) {
			throw new NoSuchUserException(_NO_SUCH_ENTITY_WITH_PRIMARY_KEY + userId);
		}
		return user;
	}
	
	public void resetPassword(String userId, String newPassword) {
		Query<User> query = datastore.createQuery(User.class);
		query.filter("_id", ObjectId.massageToObjectId(userId));
		datastore.update(query, datastore.createUpdateOperations(User.class).set("password", newPassword));
	}
	
	public void editProfileBasic(User user) {
		Query<User> query = datastore.createQuery(User.class);
		query.filter("_id", ObjectId.massageToObjectId(user.getUserId()));
		UpdateOperations<User> updateOperations = datastore.createUpdateOperations(User.class);
		updateOperations.set("firstName", user.getFirstName())
						.set("lastName", user.getLastName())
						.set("username", user.getUsername())
						.set("aboutMe", user.getAboutMe())
						.set("gender", user.getGender());
		if(Validator.isNotNull(user.getDob())) {
			updateOperations.set("dob", user.getDob());
		}
		datastore.update(query, updateOperations);
	}

	public void editAccountGeneral(User user) {
		Query<User> query = datastore.createQuery(User.class);
		query.filter("_id", ObjectId.massageToObjectId(user.getUserId()));
		datastore.update(query, datastore.createUpdateOperations(User.class)
				.set("email", user.getEmail())
				.set("username", user.getUsername())
		);
	}

	public void add(User user) {
		datastore.save(user);
	}
	
	public void editPortrait(String userId, String portraitId) {
		Query<User> query = datastore.createQuery(User.class);
		query.filter("_id", ObjectId.massageToObjectId(userId));
		datastore.update(query, datastore.createUpdateOperations(User.class)
				.set("portraitId", portraitId)
		);
	}
	
	public void editThumbnail(String userId, String thumbnailId) {
		Query<User> query = datastore.createQuery(User.class);
		query.filter("_id", ObjectId.massageToObjectId(userId));
		datastore.update(query, datastore.createUpdateOperations(User.class)
				.set("thumbnailId", thumbnailId)
		);
	}
	
	public List<User> findAll(int start, int offset, boolean ascending) {
		Query<User> query = datastore.createQuery(User.class);
		String condition = "createDate";
		if(!ascending) {
			condition = StringPool.DASH + condition;
		}
		query.limit(offset).offset(start).order(condition);
		return query.asList();
	}
	
}
